-   case: test_every_model_has_objects_queryset_available
    main: |
        from myapp.models import User
        reveal_type(User.objects)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.User]'
        reveal_type(User.objects.get())  # N: Revealed type is 'myapp.models.User*'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class User(models.Model):
                    pass

-   case: every_model_has_its_own_objects_queryset
    main: |
        from myapp.models import Parent, Child
        reveal_type(Parent.objects)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.Parent]'
        reveal_type(Child.objects)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.Child]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class Parent(models.Model):
                    pass
                class Child(Parent):
                    pass

-   case: test_model_objects_attribute_present_in_case_of_model_cls_passed_as_generic_parameter
    main: |
        from myapp.models import Base, MyModel
        base_instance = Base(MyModel)
        reveal_type(base_instance.model_cls._default_manager)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from typing import TypeVar, Generic, Type
                from django.db import models

                _T = TypeVar('_T', bound=models.Model)
                class Base(Generic[_T]):
                    def __init__(self, model_cls: Type[_T]):
                        self.model_cls = model_cls
                        reveal_type(self.model_cls._default_manager)  # N: Revealed type is 'django.db.models.manager.BaseManager[django.db.models.base.Model]'
                class MyModel(models.Model):
                    pass
                class Child(Base[MyModel]):
                    def method(self) -> None:
                        reveal_type(self.model_cls._default_manager)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'

-   case: if_custom_manager_defined_it_is_set_to_default_manager
    main: |
        from myapp.models import MyModel
        reveal_type(MyModel._default_manager)  # N: Revealed type is 'myapp.models.CustomManager[myapp.models.MyModel]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from typing import TypeVar
                from django.db import models
                _T = TypeVar('_T', bound=models.Model)
                class CustomManager(models.Manager[_T]):
                    pass
                class MyModel(models.Model):
                    manager = CustomManager['MyModel']()

-   case: if_default_manager_name_is_passed_set_default_manager_to_it
    main: |
        from myapp.models import MyModel
        reveal_type(MyModel._default_manager)  # N: Revealed type is 'myapp.models.Manager2[myapp.models.MyModel]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from typing import TypeVar
                from django.db import models

                _T = TypeVar('_T', bound=models.Model)
                class Manager1(models.Manager[_T]):
                    pass
                class Manager2(models.Manager[_T]):
                    pass
                class MyModel(models.Model):
                    class Meta:
                        default_manager_name = 'm2'
                    m1 = Manager1['MyModel']()
                    m2 = Manager2['MyModel']()

-   case: test_leave_as_is_if_objects_is_set_and_fill_typevars_with_outer_class
    main: |
        from myapp.models import MyUser
        reveal_type(MyUser.objects)  # N: Revealed type is 'myapp.models.UserManager[myapp.models.MyUser]'
        reveal_type(MyUser.objects.get())  # N: Revealed type is 'myapp.models.MyUser*'
        reveal_type(MyUser.objects.get_or_404())  # N: Revealed type is 'myapp.models.MyUser'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models

                class UserManager(models.Manager['MyUser']):
                    def get_or_404(self) -> 'MyUser':
                        pass

                class MyUser(models.Model):
                    objects = UserManager()

-   case: model_imported_from_different_file
    main: |
        from myapp.models import Inventory, Band
        reveal_type(Inventory.objects)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.main.Inventory]'
        reveal_type(Band.objects)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.Band]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models/__init__.py
            content: |
                from django.db import models
                from .main import Inventory
                class Band(models.Model):
                    pass
        -   path: myapp/models/main.py
            content: |
                from django.db import models
                class Inventory(models.Model):
                    pass

-   case: managers_that_defined_on_other_models_do_not_influence
    main: |
        from myapp.models import AbstractPerson, Book
        reveal_type(AbstractPerson.abstract_persons)  # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.AbstractPerson]'
        reveal_type(Book.published_objects)  # N: Revealed type is 'myapp.models.PublishedBookManager[myapp.models.Book]'
        Book.published_objects.create(title='hello')
        reveal_type(Book.annotated_objects)  # N: Revealed type is 'myapp.models.AnnotatedBookManager[myapp.models.Book]'
        Book.annotated_objects.create(title='hello')
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models

                class AbstractPerson(models.Model):
                    abstract_persons = models.Manager['AbstractPerson']()
                class PublishedBookManager(models.Manager['Book']):
                    pass
                class AnnotatedBookManager(models.Manager['Book']):
                    pass
                class Book(models.Model):
                    title = models.CharField(max_length=50)
                    published_objects = PublishedBookManager()
                    annotated_objects = AnnotatedBookManager()

-   case: managers_inherited_from_abstract_classes_multiple_inheritance
    main: |
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class CustomManager1(models.Manager['AbstractBase1']):
                    pass
                class AbstractBase1(models.Model):
                    class Meta:
                        abstract = True
                    name = models.CharField(max_length=50)
                    manager1 = CustomManager1()
                class CustomManager2(models.Manager['AbstractBase2']):
                    pass
                class AbstractBase2(models.Model):
                    class Meta:
                        abstract = True
                    value = models.CharField(max_length=50)
                    restricted = CustomManager2()

                class Child(AbstractBase1, AbstractBase2):
                    pass

-   case: model_has_a_manager_of_the_same_type
    main: |
        from myapp.models import UnrelatedModel, MyModel
        reveal_type(UnrelatedModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.UnrelatedModel]'
        reveal_type(UnrelatedModel.objects.first()) # N: Revealed type is 'Union[myapp.models.UnrelatedModel*, None]'

        reveal_type(MyModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
        reveal_type(MyModel.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel*, None]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class UnrelatedModel(models.Model):
                    objects = models.Manager['UnrelatedModel']()

                class MyModel(models.Model):
                    pass

-   case: manager_without_annotation_of_the_model_gets_it_from_outer_one
    main: |
        from myapp.models import UnrelatedModel2, MyModel2
        reveal_type(UnrelatedModel2.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.UnrelatedModel2]'
        reveal_type(UnrelatedModel2.objects.first()) # N: Revealed type is 'Union[myapp.models.UnrelatedModel2*, None]'

        reveal_type(MyModel2.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel2]'
        reveal_type(MyModel2.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel2*, None]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class UnrelatedModel2(models.Model):
                    objects = models.Manager()

                class MyModel2(models.Model):
                    pass

-   case: inherited_manager_has_the_proper_type_of_model
    main: |
        from myapp.models import ParentOfMyModel3, MyModel3
        reveal_type(ParentOfMyModel3.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.ParentOfMyModel3]'
        reveal_type(ParentOfMyModel3.objects.first()) # N: Revealed type is 'Union[myapp.models.ParentOfMyModel3*, None]'

        reveal_type(MyModel3.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel3]'
        reveal_type(MyModel3.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel3*, None]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class ParentOfMyModel3(models.Model):
                    objects = models.Manager()

                class MyModel3(ParentOfMyModel3):
                    pass

-   case: inheritance_with_explicit_type_on_child_manager
    main: |
        from myapp.models import ParentOfMyModel4, MyModel4
        reveal_type(ParentOfMyModel4.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.ParentOfMyModel4]'
        reveal_type(ParentOfMyModel4.objects.first()) # N: Revealed type is 'Union[myapp.models.ParentOfMyModel4*, None]'

        reveal_type(MyModel4.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel4]'
        reveal_type(MyModel4.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel4*, None]'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class ParentOfMyModel4(models.Model):
                    objects = models.Manager()

                class MyModel4(ParentOfMyModel4):
                    objects = models.Manager['MyModel4']()

# TODO: make it work someday
#-   case: inheritance_of_two_models_with_custom_objects_manager
#    main: |
#        from myapp.models import MyBaseUser, MyUser
#        reveal_type(MyBaseUser.objects)  # N: Revealed type is 'myapp.models.MyBaseManager[myapp.models.MyBaseUser]'
#        reveal_type(MyBaseUser.objects.get())  # N: Revealed type is 'myapp.models.MyBaseUser'
#
#        reveal_type(MyUser.objects)  # N: Revealed type is 'myapp.models.MyManager[myapp.models.MyUser]'
#        reveal_type(MyUser.objects.get())  # N: Revealed type is 'myapp.models.MyUser'
#    installed_apps:
#        - myapp
#    files:
#        -   path: myapp/__init__.py
#        -   path: myapp/models.py
#            content: |
#                from django.db import models
#
#                class MyBaseManager(models.Manager):
#                    pass
#                class MyBaseUser(models.Model):
#                    objects = MyBaseManager()
#
#                class MyManager(models.Manager):
#                    pass
#                class MyUser(MyBaseUser):
#                    objects = MyManager()

-   case: custom_manager_returns_proper_model_types
    main: |
        from myapp.models import User
        reveal_type(User.objects)  # N: Revealed type is 'myapp.models.User_MyManager2[myapp.models.User]'
        reveal_type(User.objects.select_related())  # N: Revealed type is 'myapp.models.User_MyManager2[myapp.models.User]'
        reveal_type(User.objects.get())  # N: Revealed type is 'myapp.models.User*'
        reveal_type(User.objects.get_instance())  # N: Revealed type is 'builtins.int'
        reveal_type(User.objects.get_instance_untyped('hello'))  # N: Revealed type is 'Any'

        from myapp.models import ChildUser
        reveal_type(ChildUser.objects)  # N: Revealed type is 'myapp.models.ChildUser_MyManager2[myapp.models.ChildUser]'
        reveal_type(ChildUser.objects.select_related())  # N: Revealed type is 'myapp.models.ChildUser_MyManager2[myapp.models.ChildUser]'
        reveal_type(ChildUser.objects.get())  # N: Revealed type is 'myapp.models.ChildUser*'
        reveal_type(ChildUser.objects.get_instance())  # N: Revealed type is 'builtins.int'
        reveal_type(ChildUser.objects.get_instance_untyped('hello'))  # N: Revealed type is 'Any'
    installed_apps:
        - myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from django.db import models
                class MyManager(models.Manager):
                    def get_instance(self) -> int:
                        pass
                    def get_instance_untyped(self, name):
                        pass
                class User(models.Model):
                    objects = MyManager()
                class ChildUser(models.Model):
                    objects = MyManager()
